<?php
namespace app\admin\controller\csmtable;

use addons\csmtable\library\CsmgenerateTask;
use addons\csmtable\library\ACsmgenerateControl;
use addons\csmtable\library\CsmTableUtils;

class Csmgenerate extends ACsmgenerateControl
{
    
    public function _initialize()
    {
        parent::_initialize();
    }

    public function generate()
    {
        set_time_limit(0);
        $request = $this->request;
        $filesource = $request->request('csmtable_filesource');
        $indexurl = $request->request('csmtable_indexurl');

        $dao = new \app\admin\model\csmtable\Xlstask();
        // 限制下载
        if (true) {
            $userinfo = $this->auth->getUserInfo();
 
            $adminId = $userinfo["id"];
            $row = $dao->where("admin_id", "=", $adminId)
                ->where("progress", "<", "100")
                ->where("createtime", ">", time() - 1800)
                ->where("iserror", "<>", "Y")
                ->find();
            if ($row) {
                $this->error("当前有下载任务，请任务结束后再尝试下载。");
            }
        }

        // 生成任务记录
        $dao->where("admin_id", "=", $adminId)
            ->where("filesource", '=', $filesource)
            ->where("status", "=", "normal")
            ->update([
            "status" => "hidden"
        ]);

        // 触发异步生成Excel任务
        $route2 = CsmTableUtils::getInstanceAndMethod($indexurl);
        $classname = $route2[0];

        $getparams = [
            'search' => $request->request('search'),
            'filter' => $request->request('filter'),
            'op' => $request->request('op'),
            'sort' => $request->request('sort'),
            'order' => $request->request('order'),
            'offset' => $request->request('offset'),
            'limit' => $request->request('limit'),
            'csmtable_classname' => str_replace('\\', '/', $classname),
            'csmtable_methodname' => $route2[1],
            'csmtable_columns' => $request->request('csmtable_columns')
        ];

 
        $param = [
            'admin_id' => $adminId,
            'filesource' => $filesource,
            'param' => json_encode($getparams),
            'createtime' => time(),
 
        ];
        $dao->create($param);
        $id = $dao->getLastInsID();

        $ret = $this->_index($id);
        if($ret===true){
            $this->success();
        }else{
            $this->error($ret);
        }
    }

 
    public function index($ids=null){
        $ret = $this->_index($ids);
        if($ret===true){
            echo "操作成功！";
        }else{
            echo $ret;
        }
    }

    private function _index($ids=null)
    {
        static::p('----generateExcelByClassname begin:');
        set_time_limit(0);
        // 根据id获取xlstask row
        $id = $this->request->request("id");
        
        //v2.1.8 增加日志和查询日志调试功能,便于排查问题(从下载任务的[测试生成Excel]按钮访问)
        if(!empty($ids)){
            $id = $ids;
        }
        
        $params = $this->getXlstaskParams($id);
        $this->setProgress($id, 10);
    
        // 按记录数切分多个任务
        $recordtotal = $this->getDataRecordTotal($params);
        
        $excelCount = (int) ($recordtotal / $this->excelmaxrecoredcount); // 总记录数/单个xls记录数=200/100=2
        
        if ($recordtotal == 0) {
            // 没有数据,则报错
            $errmsg = "没有数据，无法下载";
            $this->setErrorXlstask($id,$errmsg);
            static::p('----generateExcelByClassname end:');
            return $errmsg;
        }

        $result = '';
        $excelFiles = [];
        for ($i = 0; $i <= $excelCount; $i ++) {
            static::p($i);
            $fileno =  ($i + 1) ; 
            $offset = $i * $this->excelmaxrecoredcount;

            $task = new CsmgenerateTask();
            $filename = $task->index($id,$fileno,$offset);
            $result =  $filename .';';
  
            $progress = (int) 80 * ($i + 1) / ($excelCount + 2) + 10;
            $this->setProgress($id, $progress);
 
            
            if ($filename != null) {
                $excelFiles[] = $filename;
                static::p($filename);
            } else {
                $errmsg = '下载报错,可能是PHP内存设置过小或数据查询报错造成';
                $this->setErrorXlstask($id, $errmsg);
                return $errmsg;
            }
        }
        
        $this->setProgress($id, 90);
      
        $zipfilename = static::saveExcelToZip($excelFiles);
        $this->setProgress($id, 100, $zipfilename,$result);
        static::p('----generateExcelByClassname end:'.$result);
        //v2.1.8 增加日志和查询日志调试功能,便于排查问题
        //echo $result.'<BR>完成生成'.$zipfilename;
        return true;
    }
 
    
    public function saveExcelToZip(&$excelFiles)
    {
        $zipfn = 'csmtable_' . time() . '.zip';
        $zipfilename = $this->uploadtmppath . $zipfn;
        $zip = new \ZipArchive();
        $zip->open($zipfilename, \ZipArchive::CREATE | \ZipArchive::CREATE);
        static::p('saveExcelToZip');
        static::p($excelFiles);
        foreach ($excelFiles as $item) {
            $zip->addFile($this->uploadtmppath . $item, $item);
        }
        $zip->close();
        
        foreach ($excelFiles as $item) {
            unlink($this->uploadtmppath . $item);
        }
        return $zipfn;
    }
    
 
    
    private function setProgress(&$csmtable_xlstask_id, $progress, $filename = '',$errormsg='')
    {
        $this->xlstaskdao->where("id", "=", $csmtable_xlstask_id)->update([
            'progress' => $progress,
            'filename' => $filename,
            'updatetime' => time(),
            'errormsg'=>$errormsg//v2.1.8 增加日志和查询日志调试功能,便于排查问题
        ]);
        static::p('progress:' . $progress);
    }
    
    private function setErrorXlstask($csmtable_xlstask_id, $errormsg)
    {
        $this->xlstaskdao->where("id", "=", $csmtable_xlstask_id)->update([
            'iserror' => 'Y',
            'errormsg' => substr($errormsg, 0, 1000),
            'updatetime' => time()
        ]);
        static::p('progress:' . $errormsg);
    }
}
